/*
* 目标：实现一个五子棋游戏
* 作者：胡靖
* @param player 黑白子 1为黑 2为白
* @param winner 赢家 1为黑 2为白
*
* */

package Question2;


import java.util.Arrays;
import java.util.Scanner;

public class Game {

    private static final int NUM = 16; //棋盘大小
    private static char[][] Arr = new char[NUM + 1][NUM + 1]; // 加上坐标的矩阵大小
    private static char fill = (char)43; //棋盘样式

    public static void main(String[] args) {
        //初始化棋盘
        initBoard();
        //开始游戏
        game();
    }

    //1.初始化棋盘
    public static void initBoard() {

        //1.1初始化矩阵
        for (int i = 0; i <= NUM; i++) {
            Arrays.fill(Arr[i], fill);
        }
        //1.2生成坐标
        char[] Axis = new char[NUM];
        int m = 48;
        for (int n = 0; n < 10; n++) {
            Axis[n] = (char) m;
            m++;
        }
        m += 39;
        for (int l = 10; l < NUM; l++) {
            Axis[l] = (char) m;
            m++;
        }

        //1.3填充表盘坐标
        Arr[0][0] = (char) 32;
        for (int j = 1; j <= NUM; j++) {
            Arr[0][j] = Axis[j - 1];
            Arr[j][0] = Axis[j - 1];
        }

        //1.4打印棋盘
        for (int i = 0; i <= NUM; i++) {
            for (int j = 0; j <= NUM; j++) {
                System.out.print(Arr[i][j] + " ");
            }
            System.out.println();
        }
    }
    //2.开始游戏
    public static void game() {
        while(true){
            //开始下棋
            Chess chess = play(); //获取下棋的位置并检测
            if(chess == null) continue; //重新落子
            //如落子17 17，则结束游戏
            if(17 == chess.x && 17 == chess.y){
                System.out.println("玩家" + player + "结束游戏");
                break;
            }
            //重绘棋盘
            drawBoard(chess);
            //检测是否赢棋
            if(win(chess) != 0) {
                System.out.println("恭喜玩家" + player + "赢了!");
                break;
            }
            //交换玩家
            changePlayer(chess);
        }
    }

    //3.开始下棋
    public static Chess play() {
        //请玩家落子
        System.out.println("请玩家" + player +"落子，X,Y用空格隔开：");
        Scanner sc = new Scanner(System.in);
        int x = sc.nextInt();
        int y = sc.nextInt();

        //如位置不正确，则重新落子
        if(!check(Arr,x,y)) return null;

        return new Chess(x,y);
    }

    //4.检查落子位置是否正确
    public static boolean check(char[][] Arr, int x, int y) {
        //检测落子是否正确
        if(17 == x && 17 == y) return true;

        if(x <= 0 || x >= Arr.length) {
            System.out.println("位置错误，请重新输入");
            return false;
        }
        if(y <= 0 || y >= Arr.length) {
            System.out.println("位置错误，请重新输入");
            return false;
        }
        if(Arr[x][y] != fill) {
            System.out.println("此处已有子，请重新下");
            return false;
        }
        return true;
    }

    //5.填充棋子并重绘棋盘
    public static void drawBoard(Chess chess) {
        /*实心圆和空心圆用ASCII码在IDEA环境下打印的很奇怪，换成*和.
         * */
        if(1 == player) {
            Arr[chess.x][chess.y] = (char) 42;
        }
        else {
            Arr[chess.x][chess.y] = (char) 46;
        }
        //打印棋盘
        for (int i = 0; i <= NUM; i++) {
            for (int j = 0; j <= NUM; j++) {
                System.out.print(Arr[i][j] + " ");
            }
            System.out.println();
        }
    }

    //6.判断是否赢棋
    public static int win(Chess chess) {
        int raw = 0;
        int x = chess.x;
        int y = chess.y;

        //判断横向
        for(int i = y - 4;i < y + 5;i++) {
            if(i <= 0 || i > y) continue;
            if(Arr[x][i] == Arr[x][y]) {
                raw++;
            }
            else {
                raw = 0;
            }
            if(2 == raw) return player;
        }
        int column = 0;
        //判断纵向
        for(int j = x - 4;j < x + 5;j++) {
            if(j <= 0 || j > x) continue;
            if(Arr[j][y] == Arr[x][y]) {
                column++;
            }
            else {
                column = 0;
            }
            if(2 == column) return player;
        }
        //判断左对角
        int leftdiagonal = 0;
        for(int k = x - 4,l = y - 4;k < x + 5 && l < y + 5;k++,l++) {
            if(k <= 0 || k > x || l <= 0 || l > y) continue;
            if(Arr[k][l] == Arr[x][y]) {
                leftdiagonal++;
            }
            else {
                leftdiagonal = 0;
            }
            if(2 == leftdiagonal) return player;
        }
        //判断右对角
        int rightdiagonal = 0;
        for(int m = x - 4,n = y + 4;m < x + 5 && n > y - 5;m++,n-- ) {
            if(m <= 0 || m > x || n <= 0 || n > y) continue;
            if(Arr[m][n] == Arr[x][y]) {
                rightdiagonal++;
            }
            else {
                rightdiagonal = 0;
            }
            if(2 == rightdiagonal) return player;
        }
        return 0;
    }

    //7.交换棋手
    private static int player = 1;
    private static void changePlayer(Chess chess) {
        if(1 == player) {
            player = 2;
        }
        else {
            player = 1;
        }
    }

    //落子位置，练习内部类的编写
    static class Chess {
        public int x,y;
        public Chess(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }
}

